﻿using System;
using System.Net;
using System.Net.Mail;
using sscore;

namespace DMN_MailSender
{
    internal class Spamer
    {
        private readonly SpamerResultHandler _onSpamerResult;
        private readonly TaskParams _tprm;

        public Spamer(SpamerResultHandler onSpamerResult, TaskParams tprm)
        {
            _onSpamerResult = onSpamerResult;
            _tprm = tprm;
        }

        public virtual void DoWork()
        {
            WriteLog(String.Format("Start send mail [{0}]", _tprm.MailParams.StartTime));

            if (string.IsNullOrEmpty(_tprm.MailParams.SubjectText) && string.IsNullOrEmpty(_tprm.MailParams.BodyText))
            {
                _tprm.MailParams.ResultMessage = "Subject and Body is empty.";
                WorkWithDbData db = new WorkWithDbData(_tprm.ConnectionString, _tprm.Log);
                db.UpdateMailStatus(_tprm.MailParams);
            }
            else
            {
                while (_tprm.MailParams.Result == Consts.FALSE
                         && _tprm.MailParams.AttemptsPerformed < _tprm.MailParams.AttemptsTotal)
                {
                    if (_tprm.Ct.IsCancellationRequested)
                        break;

                    try
                    {
                        MailMessage message = new MailMessage(
                            _tprm.MailParams.AccFrom.Mail,
                            _tprm.MailParams.AccTo,
                            _tprm.MailParams.SubjectText,
                            _tprm.MailParams.BodyText
                        );
                        using (SmtpClient client = new SmtpClient(_tprm.MailParams.AccFrom.SendServer, Convert.ToInt32(_tprm.MailParams.AccFrom.SendPort)))
                        {
                            if (String.IsNullOrEmpty(_tprm.MailParams.AccFrom.SendUser))
                                client.UseDefaultCredentials = true;
                            else
                            {
                                int slashIndex = _tprm.MailParams.AccFrom.SendUser.IndexOf('\\');
                                string domain = "";
                                if (slashIndex >= 0)
                                {
                                    _tprm.MailParams.AccFrom.SendUser = _tprm.MailParams.AccFrom.SendUser.Substring(slashIndex + 1);
                                    domain = _tprm.MailParams.AccFrom.SendUser.Substring(0, slashIndex);
                                }
                                client.Credentials = new NetworkCredential(_tprm.MailParams.AccFrom.SendUser, _tprm.MailParams.AccFrom.SendPassword) { Domain = domain };
                            }
                            client.EnableSsl = _tprm.MailParams.AccFrom.SendUseSSL;
                            client.Send(message);
                        }
                        _tprm.MailParams.Result = Consts.TRUE;
                        _tprm.MailParams.ResultMessage = "";
                        WriteLog(String.Format("Mail [{0}] was successfully sent.", _tprm.MailParams.StartTime));
                    }
                    catch (Exception ex)
                    {
                        _tprm.MailParams.ResultMessage = ex.Message;
                        WriteLog(String.Format("Error of Send Mail [{0}] from account [{1}] to [{2}] on template [{3}]. {4}{5}"
                            , _tprm.MailParams.StartTime
                            , _tprm.MailParams.AccFrom.Mail
                            , _tprm.MailParams.AccTo
                            , _tprm.MailParams.MailTemplate.Name
                            , Environment.NewLine
                            , ex.Message), MessageType.Error);

                        sscore.Utils.SysUtils.Sleeps.MSeconds(_tprm.MailParams.Timeout);
                    }

                    _tprm.MailParams.AttemptsPerformed++;

                    WorkWithDbData db = new WorkWithDbData(_tprm.ConnectionString, _tprm.Log);
                    db.UpdateMailStatus(_tprm.MailParams);
                }
            }
            SetSpamerResult(_tprm);
        }

        private void SetSpamerResult(TaskParams tprm)
        {
            if (_onSpamerResult != null)
                _onSpamerResult(tprm);
        }

        private void WriteLog(string message, MessageType mt = MessageType.Info)
        {
            if (_tprm.Log != null)
                _tprm.Log(message, mt);
        }
    }
}
